#pragma once
#include "..\interfaces.h"
namespace RE
{
	namespace MEM
	{
//--------------------------------------------------------------------------------------------
//Lightning fast stack allocators. To be used in most performance critical code.
//--------------------------------------------------------------------------------------------

class IStackAllocator
{
public:
	IStackAllocator() {}
	~IStackAllocator() {}

	virtual void Initialize(U32 size) = 0;
	virtual void Destruct() = 0;
	virtual void PopFrame() = 0;
	virtual void PopStack() = 0;
	virtual void OnUpdate() = 0;
	virtual void* PushFrame(U32 size) = 0;
};
class StackAllocator : public IStackAllocator
{
public:
	StackAllocator() { m_stack_size = 0; m_stack_start = 0; m_stack_ptr = 0; }
	~StackAllocator() {}
	virtual void Initialize(U32 size);
	virtual void Destruct();
	virtual void PopFrame();
	virtual void PopStack();
	virtual void OnUpdate() { } // do nothing
	virtual void* PushFrame(U32 size);
private:
	U32 m_stack_size;
	U8 * m_stack_start;
	U8 * m_stack_ptr;
};

class SingleFrameAllocator : public StackAllocator
{
public:
	SingleFrameAllocator() {}
	~SingleFrameAllocator() {}

	void OnUpdate(); // shoud be one of the fist thing updated or the last!
private:
	void PopFrame(); // forbidden function
};



class DoubleBufferedAllocator : public IStackAllocator
{
public:
	DoubleBufferedAllocator() {}
	~DoubleBufferedAllocator() {}
	virtual void Initialize(U32 size);
	virtual void Destruct();
	virtual void PopFrame();
	virtual void PopStack();
	virtual void OnUpdate();
	virtual void* PushFrame(U32 size);
private:
	bool m_active;
	SingleFrameAllocator m_stacks[2];
};

class DoubleEndedAllocator : public IStackAllocator
{
public:
	DoubleEndedAllocator() {}
	~DoubleEndedAllocator() {}
	virtual void Initialize(U32 size);
	virtual void Destruct();

	virtual void PopFrame();
	virtual void PopFrameBack();
	virtual void PopFrameFront();

	virtual void PopStack();
	virtual void PopStackBack();
	virtual void PopStackFront();

	virtual void OnUpdate();
	virtual void* PushFrame(U32 size);
	virtual void* PushFrameBack(U32 size);
	virtual void* PushFrameFront(U32 size);
private:
	U8 * m_stack_back;
	U8 * m_stack_ptrb;
	U8 * m_stack_front;
	U8 * m_stack_ptrf;
	U32 m_stack_size;
};			




	} // end of namespace MEMORY
} // end of namespace Random Engine